package br.com.dataphonebr.service;

import java.util.List;

import javax.mail.AuthenticationFailedException;
import javax.mail.SendFailedException;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.preference.PreferenceManager;
import br.com.dataphonebr.R;
import br.com.dataphonebr.SettingsActivity;
import br.com.dataphonebr.dao.impl.UsuarioDao;
import br.com.dataphonebr.entity.Credential;
import br.com.dataphonebr.entity.Usuario;
import br.com.dataphonebr.exception.CredentialsException;
import br.com.dataphonebr.util.ActivityUtil;
import br.com.dataphonebr.util.GMailSender;
import br.com.dataphonebr.util.Util;

public class CredentialsService extends Activity{
	
	private UsuarioDao dao = null;
	private Credential credential;
	private Activity instance = null;
	private Context context;
	private Util util;
	public static final String MyPREFERENCES = "MyPrefs" ;
	public static final String USERNAME_SESSION = "nameKey"; 
	public static final String USER_SESSION = "loginKey"; 
    public static final String PASS_SESSION = "passwordKey"; 
    
    public CredentialsService(Activity instance) {
    	this.dao = new UsuarioDao(instance);
    	this.instance = instance;
    	this.util = new Util();
	}
    
    public CredentialsService(Activity instance, Context context) {
    	this.dao = new UsuarioDao(instance);
    	this.instance = instance;
    	this.context = context;
    }
    
    public boolean noUsers(){
    	List<Usuario> usuarios = dao.selectAllByStatus(true);
    	if (usuarios != null && !usuarios.isEmpty()){
    		return false;
    	}
    	return true;
    }
    
    public Usuario getUniqueUser(){
    	List<Usuario> usuarios = dao.selectAllByStatus(true);
    	if (usuarios != null && !usuarios.isEmpty()){
    		return usuarios.get(0);
    	}
    	return null;
    }
    
    public Usuario getUsuarioLogado(){
   		Usuario usuario = null;
   		if (!noUsers())
   			usuario = dao.selectByLogin(getCredential().getLogin());
   		return usuario;
    }
    
	public boolean login(String user, String pass) throws CredentialsException{
		credential = new Credential();
		Usuario usuario = dao.selectByLoginAndStatus(user, true);
		if (usuario == null){
			throw new CredentialsException(context.getString(R.string.msg_user_autentication_error));
		}
		
		if (pass == null || pass.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_password_autentication_error));
		}
		
		if (!pass.equals(usuario.getPassword())){
			throw new CredentialsException(context.getString(R.string.msg_password_autentication_error));
		}
		credential.setLogin(user);
		credential.setPassword(pass);
		credential.setName(usuario.getNome());
		credential.setLogin(usuario.getLogin());
		this.saveCredentialsPreferences();
		return true;
	}
	
	public void saveCredentialsPreferences(){
		SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(instance);
		Editor editor = sharedpreferences.edit();
		editor.putString(USERNAME_SESSION, credential.getName());
		editor.putString(USER_SESSION, credential.getLogin());
		editor.putString(PASS_SESSION, credential.getPassword());
		editor.commit();
	}

	public void logout(){
		SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(instance);	
		Editor editor = sharedpreferences.edit();
		editor.putBoolean(SettingsActivity.MANTER_CONECTADO, false);
		editor.commit();
	}
	
	public boolean resumeLogin(){
		SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(instance);
		if (sharedpreferences.contains(USER_SESSION) && sharedpreferences.contains(PASS_SESSION)){
			String user = sharedpreferences.getString(USER_SESSION, "");
			String password = sharedpreferences.getString(PASS_SESSION, "");
			try {
				if (login(user, password)){
					return true;
				}
			} catch (CredentialsException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
	
	public Credential getCredential() {
		SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(instance);
		String name = sharedpreferences.getString(USERNAME_SESSION, "");
		String user = sharedpreferences.getString(USER_SESSION, "");
		String password = sharedpreferences.getString(PASS_SESSION, "");
		if (user != null && !user.isEmpty() && password != null && !password.isEmpty()){
			credential = new Credential();
			credential.setName(name);
			credential.setLogin(user);
			credential.setPassword(password);
		}
		return credential;
	}
	
	public void checkPasswordFromUserUpdate(Usuario usuario, String passwordTyped, Context context) throws CredentialsException{
		String error = usuario.validate(false);
		if (error != null){
			throw new CredentialsException(error);
		}

		if (!usuario.getPassword().equals(passwordTyped)){
			throw new CredentialsException(context.getString(R.string.msg_password_autentication_error));
		}
	}
	
	public void checkUserFromNewPassword(Usuario usuario, String oldPassword, String newPassword, String repeatPassword, Context context) throws CredentialsException{
		String error = usuario.validate(false);
		if (error != null){
			throw new CredentialsException(error);
		}

		if (oldPassword == null || oldPassword.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_old_password_empty));
		}

		if (newPassword == null || newPassword.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_new_password_empty));
		}

		if (repeatPassword == null || repeatPassword.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_repeat_password_empty));
		}
		
		if (!usuario.getPassword().equals(oldPassword)){
			throw new CredentialsException(context.getString(R.string.msg_current_old_password_error));
		}
		
		if (!newPassword.equals(repeatPassword)){
			throw new CredentialsException(context.getString(R.string.msg_new_repeat_password_error));
		}
	}
	
	public void checkNewUser(String newPassword, String repeatPassword, Context context) throws CredentialsException{
		if (newPassword == null || newPassword.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_new_password_empty));
		}
		
		if (repeatPassword == null || repeatPassword.isEmpty()){
			throw new CredentialsException(context.getString(R.string.msg_repeat_password_empty));
		}
		
		if (!newPassword.equals(repeatPassword)){
			throw new CredentialsException(context.getString(R.string.msg_new_repeat_password_error));
		}
	}
	
	public Usuario getUserFromForgotMyPassword(String user){
		Usuario usuario = dao.selectByLogin(user);
		if (usuario == null || usuario.getCodigo() == null){
			usuario = dao.selectByEmail(user);
		}
		return usuario;
	}
	
	private volatile Throwable initException;
	
	Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
	    public void uncaughtException(Thread th, Throwable ex) {
	    	initException = ex;
	    }
	};
	
//	TODO: Acertar
	public void sendForgotMyPassword(String user) throws RuntimeException, CredentialsException{
		ActivityUtil<Usuario> acUtil = new ActivityUtil<Usuario>(instance);
		if (!acUtil.internetIsEnable()){
			throw new CredentialsException(context.getString(R.string.msg_internet_connection_failed));
		}
		final Usuario usuario = this.getUserFromForgotMyPassword(user);
		if (usuario != null){
			try {
				Thread thread = new Thread(new Runnable() {
					public void run() {
						String error = context.getString(R.string.msg_email_generic_error);
						try {
							String subject = context.getString(R.string.txt_subject_forgot_password);
							GMailSender sender = new GMailSender("dataphonebr@gmail.com", "dataphonep@ss");
							sender.sendMail(subject,getTemplate(usuario),"no-reply@dataphonebr.com", usuario.getEmail());
							} catch (SendFailedException e) {
								e.printStackTrace();
								throw new RuntimeException(e.getMessage());
							} catch (RuntimeException e) {
								e.printStackTrace();
								throw new RuntimeException(e.getMessage());
							} catch (Exception e) {
								if (e instanceof AuthenticationFailedException){
									error = context.getString(R.string.msg_email_autentication_error);
								}
								e.printStackTrace();
								throw new RuntimeException(error);
							}
						}
					});
				thread.setUncaughtExceptionHandler(h);
				thread.start();
				thread.join();
				if (initException != null)
					throw new CredentialsException(initException.getMessage());
			} catch (Exception e){
				e.printStackTrace();
				throw new RuntimeException(e.getMessage());
			}
		} else {
			throw new CredentialsException(context.getString(R.string.msg_new_not_found_user));
		}
	}	
	
	private String getTemplate(Usuario usuario){
		return context.getString(R.string.template_forgot_password, usuario.getNome(), usuario.getLogin(), usuario.getPassword());
	}
}